<template>
  <div>
    <div
      class="search-wrapper el-card__body is-always-shadow vm-manage-container-search"
    >
      <el-input
        placeholder="请输入搜索内容"
        clearable
        v-model="keyword"
        @input="getVmNodeToVmSearchAll('search')"
      />
      <el-button
        type="primary"
        class="search-wrapper-button"
        @click="addVPCFunc"
        >新 建</el-button
      >
      <div class="vm-manage-opt-btn">
        <el-button
          class="search-wrapper-button"
          type="primary"
          :disabled="!batchStartVisible"
          @click="batchOperate('start', '批量启动')"
          >批量启动</el-button
        >
        <el-button
          class="search-wrapper-button"
          type="warning"
          :disabled="!batchStopVisible"
          @click="batchOperate('stop', '批量停止')"
          >批量停止</el-button
        >
        <el-button
          class="search-wrapper-button"
          type="danger"
          :disabled="!batchVisible"
          @click="batchOperate('delete', '批量删除')"
          >批量删除</el-button
        >
      </div>
    </div>
    <div
      class="mainHeight vm-manage-container content-wrapper el-card el-card__body is-always-shadow"
    >
      <div
        class="vm-manage-left"
        ref="leftMoveRef"
        @scroll="handleScroll($event, 'scroll')"
      >
        <el-tree
          ref="treeRef"
          :props="defaultProps"
          highlight-current
          :expand-on-click-node="false"
          :data="nodeData"
          lazy
          :load="getVmNodeToVm"
          :node-key="_nodeKeys"
          :indent="6"
          :accordion="true"
          :default-expanded-keys="_expandArr"
          @node-click="handleNodeClick"
          @node-contextmenu="handleNodeContextMenu"
          @node-expand="handleNodeExpand"
          @node-collapse="handleNodeCollapse"
        >
          <template #default="{ node, data }">
            <el-tooltip effect="light" placement="right" :hide-after="0">
              <template #content>
                <span v-if="data.level === 3">
                  {{
                    data.level === 3
                      ? '状态：' +
                        (!data.generate
                          ? '未生成'
                          : data.status
                          ? '运行'
                          : '停止')
                      : ''
                  }}
                  <br />
                </span>
                名称： {{ data.label }}
                <span v-if="data.level === 3">
                  <br />
                  场景： {{ data.sceneName }}
                </span>
              </template>
              <span
                class="custom-tree-node"
                style="display: inline-block; width: 100%"
              >
                <span class="vm-manage-running-box" v-if="data.level === 3">
                  <el-icon class="vm-manage-running" v-if="data.status">
                    <SvgIcon name="vpcRunning" />
                  </el-icon>
                  <img
                    src="@/assets/datang/running_icon.png"
                    class="vm-manage-running-icon"
                    alt=""
                    v-if="data.status"
                  />
                </span>
                <el-icon
                  class="vm-manage-stopping"
                  v-if="data.level === 3 && data.generate && !data.status"
                >
                  <SvgIcon name="vpcRunning" />
                </el-icon>
                <el-icon
                  class="vm-manage-stopping"
                  v-if="data.level === 3 && !data.generate"
                >
                  <SvgIcon name="vmNoCreate" />
                </el-icon>
                <span v-text="data.label" v-if="data.level !== 3"></span>
                <span
                  v-text="data.containerID + '（' + data.label + '）'"
                  v-if="data.level === 3"
                >
                </span>
              </span>
            </el-tooltip>
          </template>
        </el-tree>
        <ul
          class="vm-manage-contextmenu"
          v-if="contextVisible"
          :style="contextmenuStyle"
        >
          <li class="vm-manage-contextmenu-title">
            <span :title="contextmenuName">{{ contextmenuName }}</span>
          </li>
          <li
            v-for="item in contextmenuLevel === 3
              ? !contextMenuNode.generate
                ? vmWareNoCreateMenu
                : vmWareMenu
              : clusterOrComputedMenu"
            @click="contextMenuClick(item)"
            :class="{
              'vm-manage-contextmenu-disabled':
                contextmenuLevel === 3
                  ? (!contextMenuNode.status && item.type === 'stop') ||
                    (contextMenuNode.status && item.type === 'start')
                  : false,
            }"
            :style="{
              cursor: (
                contextmenuLevel === 3
                  ? (!contextMenuNode.status && item.type === 'stop') ||
                    (contextMenuNode.status && item.type === 'start')
                  : false
              )
                ? 'not-allowed'
                : '',
              color: (
                contextmenuLevel === 3
                  ? (!contextMenuNode.status && item.type === 'stop') ||
                    (contextMenuNode.status && item.type === 'start')
                  : false
              )
                ? '#999'
                : '',
            }"
          >
            <span>
              <el-icon class="vm-manage-contextmenu-icon">
                <SvgIcon :name="item.icon" />
              </el-icon>
              <!--              <img :src="item.icon" alt="" class="vm-manage-contextmenu-icon">-->
              <span>{{ item.name }}</span>
            </span>
          </li>
        </ul>
      </div>
      <div class="vm-manage-move" ref="moveRef"></div>
      <div class="vm-manage-right" ref="rightMoveRef">
        <div class="vm-manage-right-title">
          <el-tag type="primary">{{ _nodeName }}</el-tag>
        </div>
        <Cluster
          :node="currentNode"
          v-if="_nodeLevel === 1"
          :treeRef="treeRef"
        ></Cluster>
        <ComputeNode
          :node="currentNode"
          v-else-if="_nodeLevel === 2"
          :treeRef="treeRef"
        ></ComputeNode>
        <Network :node="currentNode" :key="currentNode?.id" v-else></Network>
      </div>
    </div>
    <AddOrEditVPC />
  </div>
</template>
<script lang="ts" setup>
import { onMounted, onUnmounted, ref, nextTick } from 'vue';
import Cluster from '@/views/simulation/networkManage/vpcNetwork/cluster.vue';
import ComputeNode from '@/views/simulation/networkManage/vpcNetwork/computeNode.vue';
import Network from '@/views/simulation/networkManage/vpcNetwork/network.vue';
import AddOrEditVPC from '@/views/simulation/networkManage/vpcNetwork/children/addOrEditVPC.vue';
import { useMouseMoveByTree } from '@/hooks/useMouseMoveByTree';
import { useMouseDrag } from '@/hooks/useMouseDrag';
import { emitter } from '@/utils/bus';
import {
  getVmNodeAllApi,
  getNodeTreeApi,
  batchOptionByVPCApi,
  delVPCBatchApi,
  generateVPCApi,
} from '@/api/topo/simulationApi/vpc';
import { ElMessage, ElMessageBox } from 'element-plus';
import { calcContextMenuPosition } from '@/utils/contextMenuPosition';
import debounce from 'lodash/debounce';
import { useOperateStatus } from '@/pinia/modules/operateStatus';
import { throttle } from 'lodash';
let useOperate = useOperateStatus();

// 树dom
const treeRef = ref();

const _nodeKeys = 'id';

let {
  _nodeKeysArr,
  _type,
  _expandArr,
  _nodes,
  _nodeLevel,
  _nodeName,
  currentIndex,
  currentNode,
  getCurrentNodeIndex,
  handlerLevel,
  initMouseMove,
  tagSingleStatus,
  removeStatus,
  tagStatus,
} = useMouseMoveByTree();

let { dragDest } = useMouseDrag();
const leftMoveRef = ref();
const moveRef = ref();
const rightMoveRef = ref();

// 定义树默认类型
const defaultProps = {
  id: '',
  kvmID: '',
  children: 'children',
  label: 'label',
  level: 1,
  isLeaf: 'leaf',
};

const nodeData = ref([]);
const keyword = ref('');

// 一二级节点数据
let initNodeData = ref([]);

const taskFunc = data => {
  const { msg } = data;
  const info = msg.update || msg.create;

  // 创建失败
  if (info.status === 2) {
    // 只有新增需要失败了，需要加入未生成
    useOperate.operateBindTask('vpc', info, item => {
      if (item.type === 'add') {
        // 新建
        addNodeToTree();
      }
    });
  } else if (info.status === 3) {
    const vmOperate = ['start', 'stop', 'generate'];
    useOperate.operateBindTask('vpc', info, item => {
      // 启动、停止、生成（右键或者列表更新）
      if (vmOperate.includes(item.type)) {
        if (item.listItem) {
          // 获取节点数据
          let node = treeRef.value?.getNode('v-' + item.listItem.ID);

          if (node) {
            if (item.type === 'generate') {
              node.data.generate = true;
              node.data.status = false;
            } else {
              node.data.status = !node.data.status;
            }

            treeRef.value?.updateKeyChildren(node.id, node.data);
          }
        } else {
          // 获取节点数据
          let node = treeRef.value?.getNode(item.vpcID);

          if (node) {
            // 重启不变
            if (item.type !== 'restart') {
              if (item.type === 'generate') {
                node.data.generate = true;
                node.data.status = false;
                addNodeToTree();
              } else {
                node.data.status = !node.data.status;
                treeRef.value?.updateKeyChildren(item.vpcID, node);
              }
            }
          }
        }
      } else if (item.type === 'delete') {
        let node = treeRef.value?.getNode('v-' + item.listItem.ID);

        if (node) {
          treeRef.value?.remove(node);
        }

        const computerID = node.data?.computerID
          ? node.data?.computerID
          : item.computerId;
        let parentNode = treeRef.value?.getNode('c-' + computerID);

        if (parentNode?.childNodes.length === 0) {
          resolveFuncObj['c-' + computerID]([]);

          nextTick(() => {
            treeRef.value.store.nodesMap['c-' + computerID].isLeaf = false;
            treeRef.value.store.nodesMap['c-' + computerID].expanded = true;
          });
        }
      } else if (item.type === 'add') {
        addNodeToTree();
      }
    });
  }
};
// 监听websocket消息通知
emitter.on('Task', taskFunc);

/**
 * 搜索（防抖）
 */
const getVmNodeToVmSearchAll = debounce(type => {
  if (!keyword.value) {
    isScroll = false;
    getVmNodeAll(type).then(res => {
      nodeData.value = res;
    });
  } else {
    getNodeTreeApi({ keyword: keyword.value, page: 1, pageSize: -1 }).then(
      res => {
        let searchRes = res.data.list;

        // 将数据中children置为空数组
        initNodeData.value.forEach(nodeItem => {
          if (nodeItem.children && nodeItem.children.length > 0) {
            nodeItem.children.forEach(cItem => {
              cItem.children = [];
            });
          }
        });

        // 搜索
        if (type === 'search') {
          _expandArr.value = [];
        }

        // 处理树讲对应节点数据push
        searchRes.forEach(item => {
          // 遍历节点二层数据
          initNodeData.value.forEach(nodeItem => {
            if (nodeItem.children && nodeItem.children.length > 0) {
              nodeItem.children.forEach(cItem => {
                if (Number(cItem.id.substring(2)) === item.computerID) {
                  if (type === 'search') {
                    // 更新展开节点
                    if (!_expandArr.value.includes(cItem.id)) {
                      _expandArr.value.push(cItem.id);
                    }

                    if (!_expandArr.value.includes(nodeItem.id)) {
                      _expandArr.value.push(nodeItem.id);
                    }
                  }

                  // 处理节点数据
                  item.label = item.name;
                  item.id = 'v-' + item.ID;
                  item.leaf = true;
                  item.level = 3;
                  cItem.children.push(item);
                }
              });
            }
          });
        });

        if (type === 'search') {
          tagSingleStatus('_expandArr', _expandArr.value);
        }

        // 搜索关键词是否存在
        if (keyword.value) {
          // 移除无用的计算节点
          initNodeData.value.forEach(nodeItem => {
            if (nodeItem.children && nodeItem.children.length > 0) {
              let tempArr = [];
              nodeItem.children.forEach(cItem => {
                if (cItem.children && cItem.children.length > 0) {
                  tempArr.push(cItem);
                }
              });

              nodeItem.children = tempArr;
            }
          });
        }

        if (searchRes.length > 0) {
          nodeData.value = [];
          setTimeout(() => {
            nodeData.value = initNodeData.value;
          }, 100);
        } else {
          nodeData.value = [];
        }
      },
    );
  }
}, 500);

/**
 * 获取节点树（一二级数据）
 */
const getVmNodeAll = type => {
  return new Promise(resolve => {
    getVmNodeAllApi().then(res => {
      if (!(res instanceof Error)) {
        if (res.data && res.data.length > 0) {
          initNodeData.value = res.data;

          // 默认展开一级
          _expandArr.value = [];
          _nodeKeysArr.value = [];

          resolve(res.data);
          res.data.forEach(item => {
            _expandArr.value.push(item.id);

            // 收集一二级顺序id
            _nodeKeysArr.value.push(item.id);
            if (item.children?.length > 0) {
              item.children.forEach(cItem => {
                _nodeKeysArr.value.push(cItem.id);
              });
            } else {
              item.children = [];
              setTimeout(() => {
                treeRef.value.store.nodesMap[item.id].isLeaf = false;
                treeRef.value.store.nodesMap[item.id].expanded = true;
              }, 30);
            }
          });

          if (type === 'search') {
            // 展开节点（临时）
            tagSingleStatus('_expandArr', _expandArr.value);
          }
        }
      }
    });
  });
};

let resolveFunc = null;
let resolveFuncObj = {};
let tagComputedNode = null;
let tagChildren = [];
let insertIndex = -1;
/**
 * 点击计算节点懒加载
 */
const getVmNodeToVm = async (node, resolve) => {
  resolveFunc = resolve;
  // 获取懒加载底层函数调用
  if (Object.keys(node.data).length > 0) {
    // 判断是否有子级
    if (node.data.children) {
      resolve(node.data.children);
      initMouseMove(treeRef.value, _nodeKeys); // 懒加载完成后
    } else {
      // 点击计算节点加载
      if (node.data.id.indexOf('c-') !== -1) {
        resolveFuncObj[node.data.id] = resolveFunc;
        tagComputedNode = node; // 记录点击展开节点信息
        tagPage = 1; // 重置页码为1
        isScroll = false; // 重置滚动为false
        insertIndex = -1;

        const computedID = node.data.id.substring(2); // 截取实际计算节点ID
        await getSubNode(computedID);

        // 获取当前页数
        const pageIndex = Number(sessionStorage.getItem('currentNodePageVpc'));
        if (pageIndex > 1) {
          for (let i = 2; i <= pageIndex; i++) {
            await preloadHandleScroll();
            if (i === pageIndex) {
              scrollSetTimeout();
            }
          }
        } else {
          scrollSetTimeout();
        }
      }
    }
  } else {
    getVmNodeAll('').then(res => {
      resolve(res);
    });
  }
};

/**
 * 自动滚动
 */
const scrollSetTimeout = () => {
  setTimeout(() => {
    let node = treeRef.value?.getNode(currentNode.value?.id);
    if (node) {
      // 滚动到指定位置
      let element = document.querySelector(
        `[data-key='${currentNode.value?.id}']`,
      );
      element?.scrollIntoView({
        behavior: 'smooth',
        block: 'nearest',
        inline: 'nearest',
      });
    } else {
      // 单个删除虚拟机重置状态
      _nodeLevel.value = 1;
      currentNode.value = initNodeData.value[0];
      currentIndex.value = 0;

      // 获取默认节点
      _nodeName.value = initNodeData.value[0].label;
      tagStatus();
    }
  }, 300);
};

const treePageSize = 36;
let initScroll = false;
/**
 * 点击展开获取子节点
 * @param computerID
 */
const getSubNode = async computerID => {
  let vmRes = await getNodeTreeApi({
    page: tagPage,
    pageSize: treePageSize,
    computerID,
  });
  if (!(vmRes instanceof Error)) {
    // 处理数据
    const vmArr = vmRes.data.list;

    if (vmArr.length > 0) {
      // 虚拟机数据处理
      vmArr.forEach(item => {
        item.label = item.name;
        item.id = 'v-' + item.ID;
        item.leaf = true;
        item.level = 3;
      });

      if (isScroll) {
        tagChildren = [...tagChildren, ...vmArr]; // 滚动追加数据
      } else {
        tagChildren = vmArr; // 非滚动替换数据
      }
      loadMore = vmRes.data.total === tagChildren.length;
      resolveFunc(tagChildren);

      // 选中节点
      if ('' + computerID === '' + currentNode.value?.computerID) {
        setTimeout(() => {
          treeRef.value?.setCurrentKey(currentNode.value?.id, true);
        }, 300);
      }
    } else {
      resolveFunc([]);
      nextTick(() => {
        treeRef.value.store.nodesMap['c-' + computerID].isLeaf = false;
        treeRef.value.store.nodesMap['c-' + computerID].expanded = true;
      });
    }

    appendNodeKeys(vmArr, computerID);
  }
};

/**
 * 将懒加载id插入nodeKeys顺序
 * @param loadArr
 * @param computerID
 */
const appendNodeKeys = (loadArr, computerID) => {
  if (tagPage === 1) {
    for (let i = 0; i < _nodeKeysArr.value.length; i++) {
      if (_nodeKeysArr.value[i] === 'c-' + computerID) {
        insertIndex = i;
        break;
      }
    }
  }

  let loadTagArr = [];
  loadArr.forEach(item => {
    loadTagArr.push(item.id);
  });

  _nodeKeysArr.value.splice(insertIndex + 1, 0, ...loadTagArr);
  insertIndex = insertIndex + loadTagArr.length;
};

/**
 * 点击节点
 * @param data
 */
const handleNodeClick = data => {
  contextVisible.value = false;
  getCurrentNodeIndex(data);

  // 按钮状态重置
  batchStartVisible.value = false;
  batchStopVisible.value = false;
  batchVisible.value = false;
  batchSnapshotVisible.value = false;

  // 清空VPC存储
  if (_nodeLevel.value !== 3) {
    tagSingleStatus('activeIndex', 0);
  }
};

/**
 * 节点展开
 * @param node
 */
const handleNodeExpand = node => {
  let tempExpandArr = [];
  _expandArr.value.forEach(item => {
    if (item.indexOf('c-') === -1) {
      tempExpandArr.push(item);
    }
  });

  tempExpandArr.push(node.id);
  _expandArr.value = tempExpandArr;

  // 获取展开节点（临时）
  tagSingleStatus('_expandArr', _expandArr.value);
};

/**
 * 节点折叠
 * @param node
 */
const handleNodeCollapse = node => {
  for (let i = 0; i < _expandArr.value.length; i++) {
    if (_expandArr.value[i] === node.id) {
      _expandArr.value.splice(i, 1);
      break;
    }
  }

  // 获取展开节点（临时）
  tagSingleStatus('_expandArr', _expandArr.value);
};

// 右键菜单位置
const contextVisible = ref(false);
const contextmenuStyle = ref({
  top: '0px',
  left: '0px',
  'z-index': 999,
  visibility: 'hidden',
});
const contextmenuName = ref('');
const contextmenuLevel = ref(0);
const clusterOrComputedMenu = [
  { name: '创建vpc', type: 'addVPC', icon: 'contextCreate' },
];

const vmWareMenu = [
  { name: '停止', type: 'stop', icon: 'contextStop' },
  { name: '启动', type: 'start', icon: 'contextStart' },
  { name: '编辑', type: 'edit', icon: 'contextEdit' },
  { name: '删除', type: 'delete', icon: 'contextDelete' },
];

const vmWareNoCreateMenu = [
  { name: '生成', type: 'generate', icon: 'contextGenerate' },
  { name: '编辑', type: 'edit', icon: 'contextEdit' },
  { name: '删除', type: 'delete', icon: 'contextDelete' },
];

let contextMenuNode = {};
/**
 * 右键菜单
 */
const handleNodeContextMenu = (event, node) => {
  event.preventDefault(); // 阻止默认右键菜单
  event.stopPropagation(); // 阻止事件冒泡
  contextVisible.value = true;
  contextMenuNode = node;
  contextmenuLevel.value = handlerLevel(node.id);
  contextmenuName.value =
    (contextmenuLevel.value === 1
      ? '集群：'
      : contextmenuLevel.value === 2
      ? '节点：'
      : 'VPC：') +
    (contextmenuLevel.value === 1 || contextmenuLevel.value === 2
      ? node.label
        ? node.label
        : ''
      : node.containerID
      ? node.containerID
      : '');

  // 获取鼠标位置（使用clientX/clientY而不是pageX/pageY，因为我们看到UI中存在内部滚动）
  const { clientX, clientY } = event;

  // 设置初始位置为鼠标位置
  contextmenuStyle.value = {
    top: `${clientY}px`,
    left: `${clientX}px`,
    'z-index': 999,
    visibility: 'visible',
  };

  // 使用nextTick确保DOM已更新后再处理边界情况
  nextTick(() => {
    const contextMenuDOM = document.querySelector('.vm-manage-contextmenu');
    if (!contextMenuDOM) return;
    const menuHeight = contextMenuDOM.clientHeight;
    const menuWidth = contextMenuDOM.clientWidth;

    // 使用通用工具函数计算自适应位置
    const pos = calcContextMenuPosition(event, menuWidth, menuHeight, 206, 63);

    contextmenuStyle.value = {
      top: `${pos.top}px`,
      left: `${pos.left}px`,
      'z-index': 999,
      visibility: 'visible',
    };
  });
};

/**
 * 关闭右键菜单
 */
const closeContextMenu = () => {
  contextVisible.value = false;
};

const contextMenuClick = item => {
  switch (item.type) {
    case 'addVPC':
      addVPCFunc();
      break;
    case 'edit':
      emitter.emit('addOrEditVPC_bus', contextMenuNode);
      break;
    case 'delete':
      delSingle(contextMenuNode);
      break;
    case 'generate':
    case 'start':
    case 'stop':
      singleOption(item.type);
      break;
  }
};

/**
 * VPC新建
 */
const addVPCFunc = () => {
  emitter.emit('addOrEditVPC_bus');
};

// 批量状态
const batchVisible = ref(false);
const batchStartVisible = ref(false);
const batchStopVisible = ref(false);
const batchSnapshotVisible = ref(false);
let currentSelectionArr = [];
const batchOptionVisible = selectionArr => {
  // 重置状态
  batchVisible.value = false;
  batchStartVisible.value = false;
  batchStopVisible.value = false;
  batchSnapshotVisible.value = false;

  // 批量删除
  batchVisible.value = selectionArr.length > 0;

  // 批量启动、批量停止
  for (let i = 0; i < selectionArr.length; i++) {
    if (!selectionArr[i].status) {
      // 存在停止的
      batchStartVisible.value = true;
    } else if (selectionArr[i].status) {
      // 存在启动的
      batchStopVisible.value = true;
    }
  }

  currentSelectionArr = selectionArr;
};

/**
 * 删除
 * @param item
 */
const delSingle = item => {
  ElMessageBox.confirm(
    `删除VPC【${contextMenuNode?.name}】? ，删除后将不可恢复!`,
    '删除VPC',
    {
      confirmButtonText: '确 定',
      cancelButtonText: '取 消',
      type: 'warning',
      center: true,
    },
  ).then(async () => {
    delVPCBatchApi({
      ids: [Number(item?.id.substring(2))],
    }).then(res => {
      if (!(res instanceof Error)) {
        ElMessage.success(`删除成功!`);
        if (item.generate) {
          useOperate.setOperateStatus('vpc', {
            id: res.data.taskID,
            type: 'delete',
            computerId: contextMenuNode.computerID,
            listItem: { ID: item?.id.substring(2) },
          });
        } else {
          let node = treeRef.value?.getNode(item?.id);
          treeRef.value?.remove(node);

          emitter.emit('vpcUpdateData');
        }

        // 如果是在虚拟机层级
        if (_nodeLevel.value === 3) {
          // 单个删除虚拟机重置状态
          _nodeLevel.value = 1;
          currentNode.value = initNodeData.value[0];
          currentIndex.value = 0;

          // 获取默认节点
          _nodeName.value = initNodeData.value[0].label;
          tagStatus();
          setTimeout(() => {
            treeRef.value?.setCurrentKey(currentNode.value?.id, true);

            // 滚动到顶部
            let element = document.querySelector('.vm-manage-left');
            element.scrollTop = 0;
          }, 300);
        }
      }
    });
  });
};

/**
 * 单个操作
 * @param type
 */
const singleOption = type => {
  if (
    (!contextMenuNode.status && type === 'stop') ||
    (contextMenuNode.status && type === 'start')
  ) {
    return;
  }

  if (type === 'generate') {
    generateVPCApi(contextMenuNode.ID).then(res => {
      if (!(res instanceof Error)) {
        ElMessage.success(`${res.msg}`);
        useOperate.setOperateStatus('vpc', {
          id: res.data.taskID,
          type,
          vpcID: contextMenuNode?.id,
        });
      }
    });
  } else {
    batchOptionByVPCApi({
      operation: type,
      ids: [contextMenuNode.ID],
    }).then(res => {
      if (!(res instanceof Error)) {
        ElMessage.success(`${res.msg}`);
        useOperate.setOperateStatus('vpc', {
          id: res.data.taskID,
          type,
          vpcID: contextMenuNode?.id,
        });
      }
    });
  }
};

/**
 * 批量启动、停止
 * @param type
 * @param batchStr
 */
const batchOperate = (type, batchStr) => {
  // 过滤选择数据
  let filterArr = [],
    deleteArr = [];
  currentSelectionArr.forEach(item => {
    if (type === 'start' && !item.status) {
      filterArr.push(item.ID);
    }
    if (type === 'stop' && item.status) {
      filterArr.push(item.ID);
    } else if (type === 'delete') {
      filterArr.push(item.ID);
      deleteArr.push(item);
    }
  });

  if (type === 'delete') {
    ElMessageBox.confirm(
      `是否确定${batchStr}， ${batchStr}后将不可恢复!`,
      '批量操作',
      {
        confirmButtonText: '确 定',
        cancelButtonText: '取 消',
        type: 'warning',
        center: true,
      },
    ).then(async () => {
      delVPCBatchApi({
        ids: filterArr,
      }).then(res => {
        if (!(res instanceof Error)) {
          ElMessage.success(`删除成功!`);

          deleteArr.forEach(item => {
            if (item.generate) {
              useOperate.setOperateStatus('vpc', {
                id: res.data.taskID,
                type: 'delete',
                listItem: { ID: item.ID },
              });
            } else {
              let node = treeRef.value?.getNode('v-' + item?.ID);
              treeRef.value?.remove(node);
            }
          });

          emitter.emit('vpcUpdateData');
        }
      });
    });
  } else {
    ElMessageBox.confirm(`是否确定${batchStr}`, '批量操作', {
      confirmButtonText: '确 定',
      cancelButtonText: '取 消',
      type: 'warning',
      center: true,
    }).then(async () => {
      batchOptionByVPCApi({
        operation: type,
        ids: filterArr,
      }).then(res => {
        if (!(res instanceof Error)) {
          ElMessage.success(`${res.msg}`);
          filterArr.forEach(item => {
            useOperate.setOperateStatus('vpc', {
              id: res.data.taskID,
              type: 'batch',
              listItem: { ID: item },
            });
          });
        }
      });
    });
  }
};

// 是否滚动
let isScroll = false;
let tagPage = 1;
let loadMore = false;
/**
 * 滚动加载（节流）
 * @param e
 */
const handleScroll = throttle(async (e, type) => {
  if (
    !initScroll &&
    ((e &&
      e.target.scrollHeight - e.target.scrollTop <=
        e.target.clientHeight + 6) ||
      type === 'init')
  ) {
    tagComputedNode.data.children = null;
    tagPage++;

    // 已加载全部
    if (!loadMore) {
      isScroll = true;

      if (type === 'scroll') {
        sessionStorage.setItem('currentNodePageVpc', String(tagPage));
      }
      await getSubNode(tagComputedNode.data.id.substring(2));
    }
  }
}, 500);

/**
 * 滚动加载（预加载）
 */
const preloadHandleScroll = async () => {
  tagComputedNode.data.children = null;
  tagPage++;

  // 已加载全部
  if (!loadMore) {
    isScroll = true;
    await getSubNode(tagComputedNode.data.id.substring(2));
  }
};

/**
 * 添加节点
 * @param item
 */
const addNodeToTree = () => {
  loadMore = false;
  tagPage = 1;
  tagChildren = [];
  isScroll = false;
  initScroll = true;

  getVmNodeToVmSearchAll('');
};

/**
 * 编辑节点
 * @param item
 */
const updateNodeToTree = item => {
  let node = treeRef.value?.getNode('v-' + item.node?.ID);
  node.data.label = item.node?.name;
  node.data.name = item.node?.name;
  node.data.desc = item.node?.desc;
  treeRef.value?.updateKeyChildren(node.id, node.data);
};

emitter.on('handleSelection', batchOptionVisible);
emitter.on('vpc_update_task', updateNodeToTree);

/**
 * 挂载时
 */
onMounted(() => {
  _type.value = 'vpc';
  window.addEventListener('click', closeContextMenu);

  // 初始化
  if (sessionStorage.getItem('dragWidth')) {
    let dragObj = JSON.parse(sessionStorage.getItem('dragWidth'))[_type.value];
    if (dragObj) {
      leftMoveRef.value.style.width = dragObj.left;
      rightMoveRef.value.style.width = dragObj.right;
    }
  }

  dragDest(moveRef.value, leftMoveRef.value, rightMoveRef.value, _type.value);
});

/**
 * 卸载时
 */
onUnmounted(() => {
  window.removeEventListener('click', closeContextMenu);
  emitter.off('handleSelection', batchOptionVisible);
  emitter.off('vpc_update_task', updateNodeToTree);
  emitter.off('Task', taskFunc);
  currentNode.value = null;
  // removeStatus();
  // tagSingleStatus('activeIndex', 0);
});
</script>
<style lang="scss" scoped>
.vm-manage-container-search {
  :deep(.el-input) {
    width: 220px;
  }
}

.vm-manage-opt-btn {
  position: absolute;
  right: 40px;
}

.vm-manage-container {
  display: flex;
  flex-direction: row;
  padding-top: 16px;

  .vm-manage-left {
    width: 220px;
    height: 100%;
    background-color: #fff;
    overflow-y: auto;

    .vm-manage-contextmenu {
      width: 130px;
      height: auto;
      position: absolute;
      background-color: #fff;
      border-radius: 4px;
      box-shadow: 0 0 0.12rem rgba(0, 0, 0, 0.12);

      .vm-manage-contextmenu-icon {
        display: inline-block;
        width: 17px;
        height: 16px;
        margin-right: 10px;
        vertical-align: text-bottom;

        svg {
          width: 100%;
          height: 100%;
          color: #666666;
        }
      }

      .vm-manage-contextmenu-disabled {
        .vm-manage-contextmenu-icon {
          svg {
            color: #999;
          }
        }
      }

      .vm-manage-contextmenu-title {
        background-color: #eff6ff;
        font-weight: bolder;
        cursor: default;

        span {
          display: inline-block;
          width: 100%;
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }

      li {
        height: 32px;
        line-height: 32px;
        cursor: pointer;
        padding-left: 8px;

        span {
          display: inline-block;
          padding-left: 2px;
        }
      }

      li:hover {
        background-color: #eff6ff;
      }
    }

    :deep(.el-tree) {
      background-color: #fff;

      > .el-tree-node {
        > .el-tree-node__content {
          margin-top: 0;
        }
      }

      * {
        user-select: none;
      }

      .el-tree-node__content,
      .el-tree-node__label {
        height: 42px;
        line-height: 42px;
        padding: 5px 0;
      }

      .el-tree-node__content {
        padding-left: 4px !important;
      }

      .el-tree-node__content:hover {
        background: #eff6ff;
      }

      .el-tree-node.is-current > .el-tree-node__content {
        background-color: #eff6ff;
      }

      .el-tree-node__children {
        .el-tree-node__content {
          padding-left: 12px !important;
        }
      }
    }
  }

  .vm-manage-move {
    width: 1px;
    height: 100%;
    background-color: #e0e7ef;
    cursor: ew-resize;
    position: relative;
    z-index: 1;
  }

  .vm-manage-right {
    width: calc(100% - 222px);
    height: 100%;
    position: relative;

    .vm-manage-right-title {
      height: 32px;
      margin-left: 16px;
    }
  }

  .vm-manage-running-box {
    position: relative;
  }

  :deep(.el-tree-node__expand-icon) {
    font-size: 20px;
  }

  .vm-manage-running,
  .vm-manage-stopping {
    display: inline-block;
    width: 20px;
    height: 20px;
    margin-right: 4px;
    vertical-align: middle;
    color: #333;

    svg {
      width: 100%;
      height: 100%;
    }
  }

  .vm-manage-stopping {
    color: #999999;
  }

  .vm-manage-running-icon {
    display: inline-block;
    width: 14px;
    position: absolute;
    top: 6px;
    left: 12px;
  }
}
</style>
